import 'dart:io';

import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sainbainu/common/apis/account_api.dart';
import 'package:sainbainu/common/apis/common_api.dart';
import 'package:sainbainu/common/http/exception.dart';
import 'package:sainbainu/common/models/request/official_auth_request.dart';
import 'package:sainbainu/common/models/response/my_account.dart';
import 'package:sainbainu/common/models/response/upload_response.dart';
import 'package:sainbainu/common/models/response/user_info.dart';
import 'package:sainbainu/common/repositories/account_repository.dart';
import 'package:sainbainu/common/repositories/common_repository.dart';
import 'package:sainbainu/common/services/ali_oss.dart';
import 'package:sainbainu/common/services/user.dart';
import 'package:sainbainu/common/utils/compress.dart';
import 'package:sainbainu/common/utils/custom_exception.dart';
import 'package:sainbainu/common/utils/loading.dart';
import 'package:sainbainu/common/utils/util.dart';
import 'package:sainbainu/common/values/assets_subtype_cn.dart';
import 'package:sainbainu/common/widgets/widget.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import 'index.dart';

class OfficialAuthController extends GetxController {
  OfficialAuthController();

  final state = OfficialAuthState();

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    state.nameController = TextEditingController();
    state.accountRepository = AccountRepository(AccountApi());
    state.commonRepository = CommonRepository(CommonApi());

    MyAccountResponse userInfo = UserService.to.accountInfo.value;
    if (userInfo.officialFlag == 1) {
      state.nameController.text = userInfo.officialName ?? '';
      if (userInfo.officialImage != null) {
        state.authNetImage1.value = userInfo.officialImage![0];
        state.authNetImage2.value = userInfo.officialImage![1];
      }
      state.isOfficial = true;
    }
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
    state.nameController.dispose();
    UserService.to.getAccountInfo();
  }

  /// 选择认证资料1
  Future<void> handleSelectAuthImage1() async {
    if (state.isOfficial) {
      return;
    }
    AssetEntity? image = await handleChooseImage();
    if (image != null) {
      // 删除之前的oss图片
      if (state.authNetImageKeyName1 != null &&
          state.authNetImageKeyName1!.isNotEmpty) {
        AliOssService.to.deleteFile(state.authNetImageKeyName1!);
      }
      UploadResponse? res = await handleUpload(image);
      if (res != null) {
        state.authNetImage1.value = res.url;
        state.authNetImageKeyName1 = res.keyName;
      }
    }
  }

  /// 选择认证资料2
  Future<void> handleSelectAuthImage2() async {
    if (state.isOfficial) {
      return;
    }
    AssetEntity? image = await handleChooseImage();
    if (image != null) {
      // 删除之前的oss图片
      if (state.authNetImageKeyName2 != null &&
          state.authNetImageKeyName2!.isNotEmpty) {
        AliOssService.to.deleteFile(state.authNetImageKeyName2!);
      }
      UploadResponse? res = await handleUpload(image);
      if (res != null) {
        state.authNetImage2.value = res.url;
        state.authNetImageKeyName2 = res.keyName;
      }
    }
  }

  /// 选择图片
  Future<AssetEntity?> handleChooseImage() async {
    final List<AssetEntity>? result = await AssetPicker.pickAssets(
      Get.context!,
      pickerConfig: AssetPickerConfig(
        maxAssets: 1,
        requestType: RequestType.image,
        previewThumbnailSize: const ThumbnailSize.square(200),
        pathNameBuilder: (path) {
          if (path.isAll) return '最近';
          return AssetsSubtypeCn.cnMap[path.name] ?? path.name;
        },
      ),
    );
    if (result != null) {
      // 过滤图片大小
      var newImages = await Util.filterAssetsEntiteis(
        result,
        onError: (msg) => LoadingUtil.showInfo(msg),
      );
      return newImages[0];
    }
    return null;
  }

  /// 上传
  Future<UploadResponse?> handleUpload(AssetEntity image) async {
    try {
      // AssetEntity 转 file 对象
      List<File> fileList = await Util.assetEntityToFiles([image]);
      if (fileList.isEmpty) {
        throw CustomException('图片解析失败，请稍后再试');
      }
      // 压缩
      fileList = await CompressUtil().compressImages(
        CompressImagesOptions(fileList),
      );
      // 执行上传
      try {
        LoadingUtil.showLoading(text: '上传中...');
        UploadResponse res = await AliOssService.to.upFile(
          fileList[0].path,
          mediaType: UploadMediaType.image,
        );
        LoadingUtil.showSuccess('上传成功');
        return res;
      } on CustomHttpException catch (e) {
        throw CustomException(e.message);
      } catch (e) {
        throw CustomException('上传失败，请稍后再试');
      }
    } on CustomException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError(e.toString());
    }
    return null;
  }

  /// 显示认证资料1操作弹窗
  void handleShowAuthImage1Dialog() {
    if (state.authNetImage1.value == null ||
        state.authNetImage1.value!.isEmpty) {
      return;
    }

    handleShowBottomDialog(
      onPreview: () => handlePreviewImage(state.authNetImage1.value!),
      onChoose: () => handleSelectAuthImage1(),
    );
  }

  /// 显示认证资料2操作弹窗
  void handleShowAuthImage2Dialog() {
    if (state.authNetImage2.value == null ||
        state.authNetImage2.value!.isEmpty) {
      return;
    }

    handleShowBottomDialog(
      onPreview: () => handlePreviewImage(state.authNetImage2.value!),
      onChoose: () => handleSelectAuthImage2(),
    );
  }

  /// ios 风格底部选择器
  Future<void> handleShowBottomDialog({
    required VoidCallback onPreview,
    required VoidCallback onChoose,
  }) async {
    String? res = await showModalActionSheet<String>(
      context: Get.context!,
      style: AdaptiveStyle.iOS,
      actions: [
        SheetAction(
          key: 'preview',
          label: '预览'.tr,
        ),
        if (!state.isOfficial)
          SheetAction(
            key: 'choose',
            label: '重新选择'.tr,
            isDestructiveAction: true,
          ),
      ],
    );
    if (res == 'preview') {
      onPreview();
    } else if (res == 'choose') {
      onChoose();
    }
  }

  /// 预览图像
  void handlePreviewImage(String url) {
    Get.to(
      () => PhotoViewSaver(
        images: [url],
        enableDownload: false,
      ),
      transition: Transition.fadeIn,
      fullscreenDialog: true,
    );
  }

  /// 确认提交
  void handleSubmit() async {
    try {
      if (state.nameController.text.isEmpty) {
        throw CustomException('认证名称不能为空');
      }
      if ((state.authNetImage1.value == null ||
              state.authNetImage1.value!.isEmpty) &&
          (state.authNetImage2.value == null ||
              state.authNetImage2.value!.isEmpty)) {
        throw CustomException('至少上传一张证明资料');
      }
      LoadingUtil.showLoading(text: '正在提交');
      await state.accountRepository.officialAuth(OfficialAuthRequest(
        officialName: state.nameController.text,
        image: [
          state.authNetImage1.value ?? '',
          state.authNetImage2.value ?? '',
        ].where((i) => i.isNotEmpty).join(','),
      ));
      LoadingUtil.dismiss();
      await showOkAlertDialog(
        context: Get.context!,
        title: '提交成功'.tr,
        message: '认证资料提交成功，请等待系统审核'.tr,
        okLabel: '知道了'.tr,
        style: AdaptiveStyle.iOS,
      );
      Get.back();
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } on CustomException catch (e) {
      LoadingUtil.showError(e.toString());
    } catch (e) {
      LoadingUtil.showError('出错啦～');
    }
  }
}
